<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>

<script>
  //1、ES5没有作用域，用Java语言解释，外面的打印应该是不能被答应的，但是ES5却可以。
  // {
  //   var name = 'James Gosling';
  //   console.log(name);
  // }
  // console.log(name);

  //2、ES5没有块级作用，按理来说，对于if语句当中定义的name，当我们调用fun()的时候，在最外面的那个应该是不能被修改的，但因为ES5没有块级作用域，所以依然可以修改。
  // var fun;
  // if (true) {
  //   let name = 'James Gosling';
  //   fun = function () {
  //     console.log(name);
  //   }
  //   fun();
  // }


  //3、ES5没有块级作用域，在使用for循环的时候，就会出现这样一种情况。
  //当我们点击第一个按钮，我们想要的效果是后台会打印出’第一个按钮‘，但是结果却是’第四个按钮‘。
  //这种情况的出现，就是因为ES5没有块级作用域的原因，导致我们虽然是点击完第一个按钮，但是function函数回调的时候，其实i的值已经循环到了最后一个，也就是i=4.
  //所以，后台才会在我们点击第一个按钮的时候，结果显示的是’第四个按钮‘。
  //更简便一点的描述就是说，i的值因为没有作用域，它是被所有循环体所“共享”的。

  //ES6不同的是，它有了作用域，那么每一个循环体的i值就会有其自己的作用，例如i=0就是在第一个循环体才会有作用。
  //i=1就是在第二个循环体才会有作用。
  //i=2就是在第三个循环体才会有作用。
  //......以此类推。

  //为什么闭包可以解决问题，那是因为函数是一个作用域。
  var buts = document.getElementsByTagName('button');
  for (var i = 0; i < buts.length; i++) {
    (function (num) {
      buts[i].addEventListener('click', function () {
        console.log('第' + num + '个按钮！');
      })
    })(i)
  }

  // var name = 'James Gosling';
  // function fun(name){
  //   console.log(name);
  // }
  // fun(name);
  // name = 'yang haiwen ';
  // fun(name);

</script>
</body>
</html>